package etxt2db.corpus;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.HashSet;


public class BrownConverter {
	
	static String[] verbTags = new String[]{"BE","BE","BED","BEDZ","BEG","BEM","BEN","BER","BEZ"};
	static String[] adjTags = new String[]{"JJ","JJ$","JJR","JJS","JJT"};
	static String[] nounTags = new String[]{"NN","NN$","NNS","NNS$","NP","NP$","NPS$","NR","NR$","NRS"};
	static String[] proTags = new String[]{"PN","PN$","PP$","PP$$","PPL","PPLS","PPO","PPS","PPSS","WP$","WPO","WPS"};
	static String[] detTags = new String[]{"DT","DT$","DTI","DTS","DTX","WDT"};
	static String[] advTags = new String[]{"RB","RB$","RBR","RBT","RN","WRB"};
	static String[] artTags = new String[]{"AT"};
	static String[] prepTags = new String[]{"IN"};
	
	//VER, ADJ, NOU, PRO, DET, ADV, ART, PRE
	
	private static String simplifiedXmlTagCreator(String value, String tag){
		if(Arrays.asList(verbTags).contains(tag.toUpperCase())){
			return "<VER>" + value + "</VER>";
		}else if(Arrays.asList(adjTags).contains(tag.toUpperCase())){
			return "<ADJ>" + value + "</ADJ>";
		}else if(Arrays.asList(nounTags).contains(tag.toUpperCase())){
			return "<NOU>" + value + "</NOU>";
		}else if(Arrays.asList(proTags).contains(tag.toUpperCase())){
			return "<PRO>" + value + "</PRO>";
		}else if(Arrays.asList(detTags).contains(tag.toUpperCase())){
			return "<DET>" + value + "</DET>";
		}else if(Arrays.asList(advTags).contains(tag.toUpperCase())){
			return "<ADV>" + value + "</ADV>";
		}else if(Arrays.asList(artTags).contains(tag.toUpperCase())){
			return "<ART>" + value + "</ART>";
		}else if(Arrays.asList(prepTags).contains(tag.toUpperCase())){
			return "<PRE>" + value + "</PRE>";
		}
		return value;
	}
	
	private static String xmlTagCreator(String value, String tag){
		return "<" + tag + ">" + value + "</" + tag + ">";
	}
	
	private static String convertToken(String token){
		String[] pair = token.split("/");
		if(pair.length == 2){
			if(pair[0].equals(pair[1]) || pair[0].contains(",")){
				return pair[0];
			}else{
				return simplifiedXmlTagCreator(pair[0],pair[1]);
			}
		}else{
			return token;
		}
	}
	
	private static String convertSentence(String token){
		String[] tokens = token.split("( +)|(\t+)");
		String result = "";
		for(String str : tokens){
			result = result + convertToken(str) + " ";
		}
		
		return result;
	}
	
	static public String getContents(File aFile) {
	    //...checks on aFile are elided
	    StringBuilder contents = new StringBuilder();
	    
	    try {
	    	//use buffering, reading one line at a time
	    	//FileReader always assumes default encoding is OK!
	    	BufferedReader input =  new BufferedReader(new FileReader(aFile));
	    	try {
	    		String line = null; //not declared within while loop
	    		/*
	    		 * readLine is a bit quirky :
	    		 * it returns the content of a line MINUS the newline.
	    		 * it returns null only for the END of the stream.
	    		 * it returns an empty String if two newlines appear in a row.
	    		 */
	    		while (( line = input.readLine()) != null){
	    			contents.append(line);
	    			contents.append(System.getProperty("line.separator"));
	    		}
	    	} finally {
	    		input.close();
	    	}
	    } catch (IOException ex){
	    	ex.printStackTrace();
	    }
	    
	    return contents.toString();
	}
	
	/**
	  * Change the contents of text file in its entirety, overwriting any
	  * existing text.
	  *
	  * This style of implementation throws all exceptions to the caller.
	  *
	  * @param aFile is an existing file which can be written to.
	  * @throws IllegalArgumentException if param does not comply.
	  * @throws FileNotFoundException if the file does not exist.
	  * @throws IOException if problem encountered during write.
	  */
	static public void setContents(File aFile, String aContents)
	                                 throws FileNotFoundException, IOException {
	    if (aFile == null) {
	      throw new IllegalArgumentException("File should not be null.");
	    }
	    if (!aFile.canWrite()) {
	      throw new IllegalArgumentException("File cannot be written: " + aFile);
	    }

	    //use buffering
	    Writer output = new BufferedWriter(new FileWriter(aFile));
	    try {
	      //FileWriter always assumes default encoding is OK!
	      output.write( aContents );
	    }
	    finally {
	      output.close();
	    }
	}
	
	private static void convertFile(File input, File output) throws FileNotFoundException, IOException{
		String token = getContents(input);
		String[] tokens = token.split(System.getProperty("line.separator"));
		String result = "";
		for(String str : tokens){
			result = result + convertSentence(str) + System.getProperty("line.separator");
		}
		setContents(output, result);
	}
	
	private static List<String> listFilesDirectory(String dir){
		File folder = new File(dir);
	    File[] listOfFiles = folder.listFiles();
	    List<String> result = new ArrayList<String>();

	    for(File file : listOfFiles){
	    	if(file.isFile()){
	    		result.add(file.getName());
	    	}
	    }
	    
	    return result;
	}
	
	public static void main(String[] args) throws FileNotFoundException, IOException{
		String inputDir = "./resources/brown/";
		String outputDir = "./resources/simpleBrownConverted/";
		for(String file : listFilesDirectory(inputDir)){
			File inputFile = new File(inputDir, file);
			File outputFile = new File(outputDir, file);
			outputFile.createNewFile();
			convertFile(inputFile,outputFile);
		}
	}
}
